﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using GiveAQuiz.Common;
using GiveAQuiz.Client.Data.DataServices;
using GiveAQuiz.Common.Mvvm;

namespace GiveAQuiz.Questions
{
  public abstract class QuestionType : ObservableObject, IQuestionType, INotifyDataErrorInfo
  {

    QuestionDefinition _definition;

    public abstract string DisplayName
    {
      get;
    }

    public abstract UIElement Thumbnail
    {
      get;
    }

    public abstract DataTemplate EditorTemplate
    {
      get;
    }

    
    public abstract string GetAnswerText(string answerData);

    public abstract QuestionResult GetResult(string answerData);

    public abstract string QuestionData
    {
      get;
      set;
    }


    public abstract string GetAnswerData();

    public abstract string QuestionText
    {
      get;
      set;
    }

    public abstract string GetCorrectAnswerText();

    public abstract bool ValidateQuestion();

    public abstract bool ValidateAnswer();

    public virtual void UpdateDefinition()
    {
      if (Definition != null)
      {
        if (ValidateQuestion())
        {
          Definition.QuestionData = QuestionData;
          Definition.QuestionText = QuestionText;
        }
      }
    }


    public abstract UIElement AnswerPanel
    {
      get;
    }

    public QuestionDefinition Definition
    {
      get
      {
        return _definition;
      }
      set
      {
        if (value != _definition)
        {
          _definition = value;
          RaisePropertyChanged("Definition");
        }
      }
    }

    #region Validation
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>();

    public IEnumerable GetErrors(string propertyName)
    {
      return _errors[propertyName];
    }

    public bool HasErrors
    {
      get
      {
        return _errors.Any(pair => pair.Value.Count > 0);
      }
    }

    protected virtual void ClearErrors()
    {
      _errors.Clear();
      
    }

    protected virtual void ClearErrors(string propertyName)
    {
      if (_errors.ContainsKey(propertyName))
      {
        _errors[propertyName].Clear();
        RaiseErrorsChanged(propertyName);
      }
    }

    protected virtual void SetError(string propertyName, string error)
    {
      SetErrors(propertyName, new string[] { error });
    }

    protected virtual void SetErrors(string propertyName, string[] errors)
    {
      if (!_errors.ContainsKey(propertyName))
      {
        _errors[propertyName] = new List<string>();
      }

      _errors[propertyName].Clear();
      _errors[propertyName].AddRange(errors);

      RaiseErrorsChanged(propertyName);
    }

    protected virtual void RaiseErrorsChanged(string propertyName)
    {
        if (ErrorsChanged != null)
      {
        ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
      } 
    }
    #endregion






  }
}
